#ifndef _STOCHASTICMODEL_H
#define	_STOCHASTICMODEL_H

#ifdef	__cplusplus
extern "C" {
#endif
    #include "hashtable.h"
    #include "QueueNetworkModel.h"
    #include "hashtable_private.h"
    #include "hashtable_itr.h"
    #include "lib/csim.h"

    

    //Stochastic Server Selection Model
     static double visits_per_server[N_TOTAL_SERVER];
     static double * visits_per_cluster[N_LOCAL_AREA] = {&visits_per_server[0],
                                                        &visits_per_server[6],
                                                        &visits_per_server[16],
                                                        &visits_per_server[26]
                                                        };

     static double server_probability[N_TOTAL_SERVER];
     static double * cluster_probability[N_LOCAL_AREA] =    {&server_probability[0],
                                                            &server_probability[6],
                                                            &server_probability[16],
                                                            &server_probability[26]
                                                            };

     static double value_s_p[N_TOTAL_SERVER];
     static double * cluster_id[N_LOCAL_AREA] =  {&value_s_p[0],
                                                &value_s_p[6],
                                                &value_s_p[16],
                                                &value_s_p[26]
                                                };
    double  cutoff_s_p[N_TOTAL_SERVER];
    long    alias_s_p[N_TOTAL_SERVER];

    //Empirical Size Model
    double  prob_class_stochastic[N_CLASS_STOCHASTIC];
    double  value_class_stochastic[N_CLASS_STOCHASTIC];
    long    alias_class_stochastic[N_CLASS_STOCHASTIC];
    double  cutoff_class_stochastic[N_CLASS_STOCHASTIC];

    //Hybrid Size Model
    STREAM uniform_stream;
 
    double prob_hybrid[3];
    double value_hybrid[3];
    long   alias_hybrid[3];
    double cutoff_hybrid[3];
    
    STREAM lognormal_stream;
    STREAM pareto_stream;
    #define MODEL_SWITCH_SIZE 35000
    //commentare le define per far stimare i nuovi valori di ALPHA, MU, SIGMA
    //#define ALPHA_PARETO 1.228733
    //#define LOGNORMAL_MEAN 7.001194
    //#define LOGNORMAL_VARIANCE 2.119823

    //Exponential Interarrival Time Model
    STREAM exponential_stream;
    double exponential_mean;


    //Empirical Variant
    
    typedef struct size_key{
        int size;
    } SizeKey;

    typedef struct size_value{
        double probability;
        int size;
        int tested_occurrences;
    } SizeValue;

    SizeValue ** cumulative_distribution;
    int N_SIZE;

    void computeSizeProbability();
    void computeVisitsPerServer();
    void initializeStochasticServer();
    int nextStochasticServer();
    void initializeStochasticSize();
    int nextStochasticSize();
    void initializeStochasticInterarrivalTime();
    double nextStochasticInterarrivalTime();

#ifdef	__cplusplus
}
#endif

#endif	/* _STOCHASTICMODEL_H */

